import ast

from PySide6.QtGui import QStandardItemModel, QStandardItem
from 程序核心代码.mvvm重构.基础定义.基础图形项.基础图形组件.节点基础图形项 import 带布局的节点基础图形项

from 程序核心代码.ast节点.节点定义.基础定义.ast节点基础定义 import ast节点基础模型
from 程序核心代码.mvvm重构.基础定义.基础图形项.基础图形组件.子组件.表格组件 import 数据表格组件
from 程序核心代码.mvvm重构.基础定义.节点管理器.自动节点注册表 import 注册节点模型, 节点模型匹配器


class 可迭代数据类ast节点基础模型(ast节点基础模型):
    """抽象的可迭代数据节点基类"""

    def __init__(self, ast节点, 所属节点模型管理器, 节点名称, 列标题, 节点位置=None, 上级节点=None):
        self.数据列表 = []  # 存储友好的表格数据
        self.ast数据 = []  # 存储 AST 节点模型
        self.值列表= []  # 存储解析后的值
        self.显示次级节点= True
        super().__init__(ast节点, 所属节点模型管理器, 节点名称, 节点位置=节点位置, 上级节点=上级节点)
        self.列标题 = 列标题
        try:
            self.表格组件 = 数据表格组件(self.列标题, 同步函数=self.数据同步函数)
            self.图形项 = 可迭代数据类图形项(self)
            self.初始化接口()
        except Exception as e:
            print(f"初始化节点失败: {e}")

    def 节点数据解析(self):
        """解析节点数据，供子类实现"""
        raise NotImplementedError("需要在子类中实现此方法")

    def 初始化接口(self):
        """初始化接口"""
        模型 = self._加载_数据()
        self.表格组件.设置数据(模型)
        if self.显示次级节点:
            索引=1
            for 当前节点 in  self.值列表:
                if 当前节点:
                    结束接口 = self.添加接口到节点("数据流", "输入", 接口名称="值 " + str(索引), 必须连接=False,接口序号=索引)
                    起始接口 = 当前节点.添加接口到节点("数据流", "输出", )
                    起始接口.接口创建连接线模型(结束接口, self)
                索引+=1
    def 数据同步函数(self, 行, 列, 内容, 操作类型=None):
        """数据同步回调，增删改查"""
        print(f"数据已同步 - 行: {行}, 列: {列}, 内容: {内容}, 操作类型: {操作类型}")

        if 操作类型 == "修改":
            self._修改_ast(行, 列, 内容)
        elif 操作类型 == "添加":
            self._添加_ast(行, 内容)
        elif 操作类型 == "删除":
            self._删除_ast(行)
        self.更新接口和图形()


    def _加载_数据(self):
        """加载数据到表格模型"""
        模型 = QStandardItemModel()
        模型.setColumnCount(len(self.列标题))
        模型.setRowCount(len(self.数据列表))
        模型.setHorizontalHeaderLabels(self.列标题)
        for 行索引, 行数据 in enumerate(self.数据列表):
            for 列索引, 值 in enumerate(行数据):
                模型.setItem(行索引, 列索引, QStandardItem(str(值)))
        return 模型
    def _生成_ast值(self, 内容):
        """将字符串内容转换为 AST 节点模型"""
        try:
            # 解析为 Python AST 表达式
            表达式 = ast.parse(内容, mode="eval").body
            return 表达式
        except Exception as e:
            raise ValueError(f"无法解析表达式: {内容}, 错误: {e}")
    def _解析_ast值(self, 节点):
        """解析 AST 节点为可读字符串"""
        return ast.unparse(节点)
    def 更新接口和图形(self):
        """更新接口和图形以反映 AST 的变更"""
        # 判断是不是嵌套数据节点 进行向上传播。

        if self.上级节点 and isinstance(self.上级节点, 可迭代数据类ast节点基础模型):
            print("上级节点是可迭代数据类节点")
            self.嵌套节点处理()
        else:
            print("上级节点不是可迭代数据类节点")
            self.状态重置()
            self.节点数据解析()
            self.初始化接口()
        print("接口和图形已更新")
        print(ast.dump(self.所属节点模型管理器.ast结构树, annotate_fields=True, indent=4))
    def 状态重置(self):
        print("状态重置")
        if self.显示次级节点:
            for 当前节点 in self.值列表:
                if 当前节点:
                    当前节点.删除节点()
            self.值列表.clear()
    def 嵌套节点处理(self):
        self.上级节点.更新接口和图形()
        self.删除节点()
    def 删除节点(self,要删除的节点=None):
        # print('删除节点操作的当前节点',起始接口)
        if self._ast节点 in self.所属节点模型管理器._ast节点:
            self.所属节点模型管理器._ast节点.remove(self._ast节点)
        # 从图形角度删除所有内容
        if self.图形项:
            for 当前接口 in self.接口集合:
                if len(当前接口.接口连接线模型列表) > 0:
                    for 关系 in 当前接口.接口连接线模型列表:
                        当前接口.从接口删除关系(关系)

            self.图形项.删除当前图形项()
        if len(self._下级节点列表)>0:
            for 当前节点 in self._下级节点列表:
                #暂不考虑节点复用问题
                if 当前节点:
                    当前节点.上级节点=None
                    当前节点.删除节点()

class 可迭代数据类图形项(带布局的节点基础图形项):
    def __init__(self, 节点定义, 父项=None):
        super().__init__(节点定义, 父项)
        # 起始接口.参数区布局 .addItem(起始接口.节点定义.表格组件)
        # 起始接口.重新排列连接区()
        #起始接口.容器清空(起始接口.介绍文本容器)
        # 起始接口.布局清空(起始接口.介绍布局)
        # 起始接口.介绍文本 = None
        # 起始接口.介绍文本容器=None
        # 起始接口.参数容器=节点定义.表格组件


# 元组节点
@注册节点模型(ast.Tuple)
class 元组节点(可迭代数据类ast节点基础模型):
    """元组节点"""
    def __init__(self, ast节点, 所属节点模型管理器, 节点位置=None, 上级节点=None,节点名称="元组节点"):
        super().__init__(ast节点, 所属节点模型管理器,节点名称, 列标题=["值"], 节点位置=节点位置, 上级节点=上级节点)

    def 节点数据解析(self):
        self.数据列表 = [[self._解析_ast值(e)] for e in self._ast节点.elts]
        if self.显示次级节点:
            for 当前节点 in self._ast节点.elts:
                if isinstance(当前节点, ast.Constant):
                    self.值列表.append(None)
                else:
                    当前处理节点 = 节点模型匹配器(当前节点, self.所属节点模型管理器, 上级节点=self)
                    self.值列表.append(当前处理节点)

    def _修改_ast(self, 行, 列, 内容):
        """修改元组 AST"""
        print(f"修改元组 AST - 行: {行}, 列: {列}, 内容: {内容}")
        if 行 < len(self._ast节点.elts):
            self._ast节点.elts[行] = self._生成_ast值(内容)

    def _添加_ast(self, 行, 内容):
        """添加元素到元组 AST"""
        新值 = self._生成_ast值(内容)
        self._ast节点.elts.insert(行, 新值)

    def _删除_ast(self, 行):
        """删除元组 AST 的元素"""
        if 0 <= 行 < len(self._ast节点.elts):
            self._ast节点.elts.pop(行)
# 列表节点
@注册节点模型(ast.List)
class 列表节点(元组节点):
    """列表节点"""
    def __init__(self, ast节点, 所属节点模型管理器, 节点位置=None, 上级节点=None):
        super().__init__(ast节点, 所属节点模型管理器, 节点位置=节点位置, 上级节点=上级节点,节点名称 = "列表节点")
@注册节点模型(ast.Set)
class 集合节点(元组节点):
    """集合节点"""
    def __init__(self, ast节点, 所属节点模型管理器, 节点位置=None, 上级节点=None):
        super().__init__(ast节点, 所属节点模型管理器, 节点位置=节点位置, 上级节点=上级节点,节点名称 = "集合节点")
# 字典节点
@注册节点模型(ast.Dict)
class 字典节点(可迭代数据类ast节点基础模型):
    """字典节点"""

    def __init__(self, ast节点, 所属节点模型管理器, 节点位置=None, 上级节点=None):
        super().__init__(ast节点, 所属节点模型管理器, "字典节点", 列标题=["键", "值"], 节点位置=节点位置, 上级节点=上级节点)

    def 节点数据解析(self):
        keys = self._ast节点.keys
        values = self._ast节点.values
        self.数据列表 = [
            (self._解析_ast值(k), self._解析_ast值(v))
            for k, v in zip(keys, values)
        ]
        if self.显示次级节点:
            for 当前节点 in self._ast节点.values:
                if isinstance(当前节点, ast.Constant):
                    self.值列表.append(None)
                else:
                    当前处理节点 = 节点模型匹配器(当前节点, self.所属节点模型管理器, 上级节点=self)
                    self.值列表.append(当前处理节点)

    def _修改_ast(self, 行, 列, 内容):
        """修改字典 AST"""
        print(f"修改字典 AST - 行: {行}, 列: {列}, 内容: {内容}")
        if 0 <= 行 < len(self._ast节点.keys):
            if 列 == 0:
                self._ast节点.keys[行] = self._生成_ast值(内容)
            elif 列 == 1:
                self._ast节点.values[行] = self._生成_ast值(内容)
    def _添加_ast(self, 行, 内容):
        """添加新的键值对到字典 AST"""
        键, 值 = 内容.split(",")  # 假设新内容为 "键,值"
        新键 = self._生成_ast值(键.strip())
        新值 = self._生成_ast值(值.strip())
        self._ast节点.keys.insert(行, 新键)
        self._ast节点.values.insert(行, 新值)
    def _删除_ast(self, 行):
        """从字典 AST 中删除键值对"""
        if 0 <= 行 < len(self._ast节点.elts):
            self._ast节点.keys.pop(行)
            self._ast节点.values.pop(行)



